﻿// -----------------------------------------------------------------------
// <copyright company="Christoph van der Fecht - VDsoft">
// Copyright (C) Christoph van der Fecht - VDsoft - All Rights Reserved
// Unauthorized copying of this file, via any medium is strictly prohibited,
// unless it is communicated and authorized by the copyright owner.
// </copyright>
// -----------------------------------------------------------------------

namespace SeriesManager.Model
{
	using System;
	using System.Collections.Generic;
	using System.ComponentModel;
	using System.Linq;
	using System.Linq.Expressions;
	using System.Text;
	using System.Threading.Tasks;
	using GalaSoft.MvvmLight;

	/// <summary>
	/// An episode of a series.
	/// </summary>
	public class Episode : ObservableObject
	{
		/// <summary>
		/// The SeasonsNumber.
		/// </summary>
		private Season season = null;

		/// <summary>
		/// The EpisodeNumber.
		/// </summary>
		private int episodeNumber = 0;

		/// <summary>
		/// The EpisodeName.
		/// </summary>
		private string episodeName = string.Empty;

		/// <summary>
		/// The EpisodePath.
		/// </summary>
		private string episodePath = string.Empty;

		/// <summary>
		/// Initializes a new instance of the <see cref="Episode"/> class.
		/// </summary>
		public Episode()
		{

		}

		/// <summary>
		/// Initializes a new instance of the <see cref="Episode"/> class.
		/// </summary>
		/// <param name="path">Path of the episode file.</param>
		public Episode(string path)
		{
			if (string.IsNullOrEmpty(path))
			{
				throw new ArgumentNullException("path", "Path must not be null or empty.");
			}

			this.EpisodePath = path;
		}

		/// <summary>
		/// Gets or sets the SeasonsNumber property.
		/// </summary>
		public Season Season
		{
			get
			{
				return this.season;
			}

			set
			{
				if (value == this.season)
				{
					return;
				}

				this.season = value;
				this.RaisePropertyChanged();
			}
		}

		/// <summary>
		/// Gets or sets the EpisodeNumber property.
		/// </summary>
		public int Number
		{
			get
			{
				return this.episodeNumber;
			}

			set
			{
				if (value == this.episodeNumber)
				{
					return;
				}

				this.episodeNumber = value;
				this.RaisePropertyChanged();
			}
		}

		/// <summary>
		/// Gets or sets the EpisodeName property.
		/// </summary>
		public string Name
		{
			get
			{
				return this.episodeName;
			}

			set
			{
				if (value == this.episodeName)
				{
					return;
				}

				this.episodeName = value;
				this.RaisePropertyChanged();
			}
		}

		/// <summary>
		/// Gets or sets the EpisodePath property.
		/// </summary>
		public string EpisodePath
		{
			get
			{
				return this.episodePath;
			}

			set
			{
				if (value == this.episodePath)
				{
					return;
				}

				this.episodePath = value;
				this.RaisePropertyChanged();
			}
		}

		/// <summary>
		/// Converts an <see cref="TVDB.Model.Episode"/> into an <see cref="Episode"/>.
		/// </summary>
		/// <param name="toConvert"><see cref="TVDB.Model.Episode"/> to convert.</param>
		/// <returns>The <see cref="Episode"/> with all details.</returns>
		public static explicit operator Episode(TVDB.Model.Episode toConvert)
		{
			if (toConvert == null)
			{
				return null;
			}

			Episode converted = new Episode()
			{
				Name = toConvert.Name,
				Number = toConvert.Number
			};

			return converted;
		}

		/// <summary>
		/// Updates all details received from the TVDB.
		/// </summary>
		/// <param name="details"><see cref="TVDB.Model.Episode"/> to read the details.</param>
		public void UpdateDetails(TVDB.Model.Episode details)
		{
			if (details == null)
			{
				throw new ArgumentNullException("details", "Provided details from the database must not be null");
			}

			this.Name = details.Name;
			this.Number = details.Number;
		}

		/// <summary>
		/// Creates the filename of the episode.
		/// </summary>
		/// <returns>Filename containing seriesname, season number, episode number and episode name.</returns>
		public override string ToString()
		{
			if (string.IsNullOrEmpty(this.Name) ||
				this.Season == null || 
				this.Number == 0 ||
				this.Season.Series == null)
			{
				return string.Empty;
			}

			string pattern = "{0} S{1}E{2} - {3}";

			string seasonNumber = string.Empty;
			if (this.Season.Number < 10)
			{
				seasonNumber = this.Season.Number.ToString("D2");
			}
			else
			{
				seasonNumber = this.Season.Number.ToString();
			}

			string episodeNumber = string.Empty;
			if (this.Number < 10)
			{
				episodeNumber = this.Number.ToString("D2");
			}
			else
			{
				episodeNumber = this.Number.ToString();
			}

			return string.Format(pattern, this.Season.Series.Name, seasonNumber, episodeNumber, this.Name);
		}
	}
}
